package de.slothsoft.commons.swing.window.phase;

import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;

import de.slothsoft.commons.res.CommonMessages;
import de.slothsoft.commons.swing.CenterLayout;
import de.slothsoft.commons.swing.ImagePanel;
import de.slothsoft.commons.swing.window.AbstractMainFrame;

public abstract class AbstractPhaseMainFrame<I> extends AbstractMainFrame {

	private static final long serialVersionUID = 3709427173007565775L;

	public static final String ID_COMPONENTS = "COMPONENT_MAIN_COMPONENTS";
	public static final String ID_TITLE = "COMPONENT_TITLE";

	private PhaseChangerPanel<Phase<String>, String> mainPhasePanel;
	private PhasePanel<I> componentsPhasePanel;

	private List<Phase<I>> componentPhases;

	@Override
	protected Component createComponents() {
		this.mainPhasePanel = new PhaseChangerPanel<>(createMainPhases());
		return this.mainPhasePanel;
	}

	private List<Phase<String>> createMainPhases() {
		List<Phase<String>> mainPhases = new ArrayList<>();
		mainPhases.add(new Phase<String>(ID_TITLE, ID_TITLE) {

			@Override
			protected Container createBaseComponent() {
				return new ImagePanel();
			}

			@Override
			protected void createControls(Container parent) {
				createTitleControls((ImagePanel) parent);
			}

		});
		mainPhases.add(new Phase<String>(ID_COMPONENTS, ID_COMPONENTS) {

			@Override
			protected void createControls(Container parent) {
				createComponentsControls(parent);
			}

		});
		mainPhases.get(1).createControls();
		addAdditionalMainPhases(mainPhases);
		return mainPhases;
	}

	protected void addAdditionalMainPhases(List<Phase<String>> mainPhases) {
		// to be overridden by children
	}

	protected void createTitleControls(ImagePanel parent) {
		parent.setLayout(new CenterLayout());
		parent.add(createTitleControl());
	}

	protected Component createTitleControl() {
		final PhaseChanger<I> originalPhaseChanger = this.componentsPhasePanel.getPhaseChangerPanel();
		return new PhaseNavigationPanel<>(this.componentsPhasePanel.getPhases(), new PhaseChanger<I>() {

			@Override
			public void changeToPhase(I id) {
				changeMainPhase(ID_COMPONENTS);
				originalPhaseChanger.changeToPhase(id);
			}
		});
	}

	protected void createComponentsControls(Container parent) {
		this.componentPhases = createComponentPhases();
		this.componentsPhasePanel = new PhasePanel<>(this.componentPhases);
		addBackButton(this.componentsPhasePanel);
		parent.setLayout(new GridLayout(1, 1));
		parent.add(this.componentsPhasePanel);
	}

	private void addBackButton(PhasePanel<I> phasePanel) {
		phasePanel.getPhaseNavigationPanel().addPlaceholder();
		phasePanel.getPhaseNavigationPanel().addPhaseNavigation(
				new Phase<I>(null, CommonMessages.getString("Common.back")) {

					@Override
					protected void createControls(Container parent) {
						// nothing to do here...
					}
				}, new PhaseChanger<I>() {

					@Override
					public void changeToPhase(I id) {
						changeMainPhase(ID_TITLE);
					}
				});
	}

	protected abstract List<Phase<I>> createComponentPhases();

	public void changeMainPhase(String id) {
		this.mainPhasePanel.changeToPhase(id);
	}

	public void changeComponentsPhase(I id) {
		this.componentsPhasePanel.changeToPhase(id);
	}

	public final PhasePanel<I> getComponentsPhasePanel() {
		return this.componentsPhasePanel;
	}

	public final PhaseChangerPanel<Phase<String>, String> getMainPhasePanel() {
		return this.mainPhasePanel;
	}

	public final List<Phase<I>> getComponentPhases() {
		return this.componentPhases;
	}
}
